package simple.form.dao;

import simple.form.controller.SysContent;
import simple.form.db.Session;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * Created by Administrator on 2017/3/6.
 */
public abstract class SqlExecutor<T> {
    /*sql 语句创建器*/
    public static SqlCreator  sqlCreator = SysContent.sqlCreator;

    /**
     * 创建查询语句
     * @param bean
     * @return
     */
    public  String createFindSql(T bean){
        return sqlCreator.createFind(bean);
    }

    /**
     * 创建insert语句
     * @param bean
     * @return
     */
    public  String createInsertSql(T bean){
        return  sqlCreator.createInsert(bean);
    }

    /**
     *创建update语句,根据key进行update
     * @param bean
     * @return
     */
    public  String createUpdateByKeySql(T bean){
        return sqlCreator.createUpdateByKey(bean);
    }

    /**
     * 创建delete语句
     * @param bean
     * @return
     */
    public  String createDeleteSql(T bean){
        return  sqlCreator.createDelete(bean);
    }

    /**
     * 设置实体对象的值
     * @param bean 初始化的实体类
     * @param resultSet 查询的结果集
     * @param field 结果集字段
     * @param fieldType 字段类型
     * @return
     */
    public  T initBean(T bean,ResultSet resultSet,String field,Class fieldType){
        Class beanClass = bean.getClass();
        String firstCode;
        String otherCode;
        Method setMethod;
        //获取字段的第一个字符，并设置为大写
        firstCode = field.substring(0,1);
        firstCode = firstCode.toUpperCase();
        //字段除了第一个字符的字符串
        otherCode = field.substring(1);

        Object result = null;

        try {
            result = Table.convertResultSet(resultSet.getString(field), (Class)fieldType);
            setMethod = beanClass.getMethod(String.format("set%s%s",firstCode,otherCode),(Class)fieldType);
            setMethod.invoke(bean,result);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }catch (SQLException e) {
            e.printStackTrace();
        }
        return bean;


    }

    /**
     * 实例化实体对象
     * @param beanClass 实体对象类型
     * @return
     */
    public T newBeanInstance(Class beanClass){
        T loadBean = null;
        try {
            loadBean = (T)beanClass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return loadBean;
    }

    /**
     * 查找一个
     * @param sql
     * @param beanClass
     * @return
     */
    public abstract T findOne(String sql,Class beanClass);

    /**
     * 查找一个
     * @param bean
     * @return
     */
    public abstract T findOne(T bean);
    /**
     * 通过sql获取结果集
     * @param sql,beanClass 返回结果entity类型
     * @return
     */
    public abstract List<T> findAll(String sql,Class beanClass);
    /**
     * 查询结果
     * @param bean
     * @return
     */
    public abstract List<T> findAll(T bean);

    /**
     * insert操作
     * @param bean
     * @return
     */
    protected abstract int insert(T bean);

    /**
     * update操作
     * @param bean
     * @return
     */
    protected abstract int updateByKey(T bean);

    /**
     * delete操作
     * @param bean
     * @return
     */
    protected abstract int delete(T bean);

    /**
     * 关闭结果集操作
     * @param resultSet
     */
    protected  void closeresultSet(ResultSet resultSet){
        try {
            if(resultSet!=null){
                resultSet.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取当前的Connection
     * @return
     */
    public static  Connection getCurrentConnection(){
        Connection conn = null;
        try {
            conn = Session.getCurrentConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return  conn;
    }

    /**
     * 关闭PreparedStatement
     * @param ps
     */
    public void closePreparedStatement(PreparedStatement ps){
        try {
            ps.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 执行sql
     * @param sql
     * @return
     */
    public int executeSql(String sql){
        int count = 0;
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            conn = getCurrentConnection();
            ps = conn.prepareStatement(sql);
            count = ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            closePreparedStatement(ps);
        }
        return count;
    }
}
